#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <set>
#include <map>

using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::set;
using std::map;
using std::ifstream;
using std::ofstream;
using std::istringstream;
using std::stringstream;
using std::basic_istringstream;

#define ERROR_CHECK(cond, msg, cleanup) \
    do{ \
        if(cond) { \
            std::cerr << "Error:" << msg << "(" << __FILE__ << ":" << __LINE__ << ")" << std::endl; \
            cleanup; \
            return; \
        } \
    }while(0)

class TextQuery{
public:
    //......
    void readFile(const string & filename);
    void query(const string & word);//

private:
    //......
    vector<string> _lines;//O(1)
    map<string, set<int> > _wordNumbers;//the the
    map<string, int> _dict;//
};

void TextQuery::readFile(const string & filename){
    // 1. 打开文件
    ifstream ifs(filename);
    ERROR_CHECK(!ifs.good(), "ifstream is not good", ifs.close());

    // 2. 录入行号
    string line;
    size_t line_index = 0;
    while(getline(ifs, line)){
        _lines.push_back(line);
        
        // 录入单词
        istringstream iss(line);
        string word;
        while(iss >> word){
            _dict[word]++;
            _wordNumbers[word].insert(line_index + 1);
        }
        ++line_index;
    }
}

void TextQuery::query(const string& word){
    cout << word << "出现" << _dict[word] << "次，所在行: \n";
    for(int line_index : _wordNumbers[word]){
        cout << "行" << line_index << ":" << _lines[line_index - 1] << endl;
    }
}

//程序测试用例
int main(int argc, char *argv[])
{
    string queryWord("year");

    TextQuery tq;
    tq.readFile("china_daily.txt");
    tq.query(queryWord);
    return 0;
}
